﻿using System;
using System.Collections.Generic;
using Gp.Input;
using Gp.Scripts.Core;
using Shapes;
using UnityEngine;
using UnityEngine.InputSystem;

namespace Gp.Scripts.GUI {
    public class RotateIndicator : MonoBehaviour {
        [SerializeField] private GameObject towardsShowWithSelection;
        [SerializeField] private GameObject towardsShowWithMouse;

        [SerializeField] private float lineOffsetSpeed = 0.02f;
        [SerializeField] private List<Line> offsetLines;
        
        [SerializeField] private List<Disc> offsetDiscs;
        [SerializeField] private float discsOffsetSpeed =  0.02f;


        [SerializeField] private float maxOuterRoundOffset = 0.5f;
        [SerializeField] private float offsetAmount = 2f;
        [SerializeField] private Disc outDiscWithMouse;
        [SerializeField] private Triangle outShapeWithMouse;


        [SerializeField] private Triangle transparentPlane;
        [SerializeField] private Color clickColor;

        [SerializeField] private GameObject container;
            
        private Vector3 _temp;
        private float _tempRadius;
        
        private Color _tempColorA;
        private Color _tempColorB;
        private Color _tempColorC;


        private float _tempRound;
        private float _targetRound;
        
        private BaseUnit _currentUnit;

        private void Start() {
            _temp = outShapeWithMouse.transform.localPosition;
            _tempRadius = outDiscWithMouse.Radius;
            
            
            _tempColorA = transparentPlane.ColorA;
            _tempColorB = transparentPlane.ColorB;
            _tempColorC = transparentPlane.ColorC;
            _tempRound = transparentPlane.Roundness;


            _targetRound = _tempRound;
        }

        private void Update() {
            if (_currentUnit == null || !container.activeInHierarchy) {
                return;
            }
            
            var position = towardsShowWithMouse.transform.position;
            

            if (!InputManager.MouseRayHit(out var hit)) {
                return;
            }

            var hitPoint = hit.point;
            hitPoint.y = position.y;
            towardsShowWithMouse.transform.LookAt(hitPoint);



            var hitDistance = Vector3.Distance(hitPoint, position);
            var offset = Mathf.Atan(hitDistance * offsetAmount) * 2 * maxOuterRoundOffset/ Mathf.PI;
            outDiscWithMouse.Radius = _tempRadius + offset;
            var tempPos = _temp;
            tempPos.z += offset;
            outShapeWithMouse.transform.localPosition = tempPos;
            towardsShowWithSelection.transform.localScale = Vector3.one * (1 + offset/3);
            
            
            
            #region SelectionMark
            var selectionEulerAngles = towardsShowWithMouse.transform.localEulerAngles;
            Vector3 selectionRotation = selectionEulerAngles;
            selectionRotation.y = ((int) ((selectionEulerAngles.y + 30) / 60) % 6) * 60;
            towardsShowWithSelection.transform.localEulerAngles =
                Vector3.Lerp(towardsShowWithSelection.transform.localEulerAngles, selectionRotation, 60f * Time.deltaTime);
            #endregion

            
            
            #region Click

            if (Mouse.current.leftButton.isPressed) {
                ClickEffect();
            } else if (Mouse.current.leftButton.wasReleasedThisFrame) {
                CallBack(selectionRotation.y);
            }else {
                ReCoverClickEffect();
            }

            transparentPlane.Roundness = Mathf.Lerp(_targetRound, transparentPlane.Roundness, 0.0001f * Time.deltaTime);

            #endregion
        }

        
        private void FixedUpdate() {
            offsetDiscs?.ForEach(d => d.DashOffset += discsOffsetSpeed);
            offsetLines?.ForEach(l => l.DashOffset += lineOffsetSpeed);
        }


        private void ClickEffect() {
            transparentPlane.ColorA = clickColor;
            var temp = clickColor;
            temp.a = 0;
            
            
            transparentPlane.ColorB = temp;
            transparentPlane.ColorC = temp;
            _targetRound = 0.8f;
            
        }


        private void ReCoverClickEffect() {
            transparentPlane.ColorA = _tempColorA;
            transparentPlane.ColorB = _tempColorB;
            transparentPlane.ColorC = _tempColorC;
            _targetRound = _tempRound;
            
        }
        
        public void Display(BaseUnit unit, Vector3 destination) {
            container.transform.position = destination + new Vector3(0.02f, 0.02f, 0.02f);
            this.container.SetActive(true);
            this._currentUnit = unit;
        }
        
        public void Clear() {
            this.container.SetActive(false);
        }

        public void CallBack(float angle) {
            int rotation = (int) angle / 60;
            throw new Exception($"[{rotation}] Out of range");
        }
    }
}